const eventEmit = require('./utils/MyEventEmit')
const webSocketServer = require('./utils/WebsocketServer');
const chalk = require("chalk");
const {isOpenMockSocket} = require("./config/config");
const {fromJS} = require('immutable');
const {smoothFilter} = require("./utils");
let cli = null;
webSocketServer.on('connection', client => {
    console.log('ws connect');
    cli = client;
})
const breathDataLength = 300; //呼吸收集的总长度，主要是用来传输
module.exports = class Breath {
    startRecordTime = Number.MAX_SAFE_INTEGER;   // 收到信号开始记录数据，用来生成文件
    endRecordTime = Number.MAX_SAFE_INTEGER;     // 收到信号结束记录数据，用来生成文件
    recordedData = [];     // 生成文件的数据。
    totalRecordedCount = 0;   // 记录总共收到的数据个数

    startTimestamp = 0;  // 开始接收传感器信号的初始时间
    isRecording = false;  // 总的是否在record

    preTime = 0

    total = 0

    amplify = 1

    collectData = [];

    windowLength = 20;

    window_data = [];

    constructor() {
        this.init();
    }

    init() {
        this.listenToData();
    }
    setAmplify(val){
        if (val === 0){
            this.amplify = 1;
        }else {
            this.amplify = 1 + val / 10;
        }
    }

    listenToData() {
        eventEmit.on('breathData', data => {
            // if (this.startTimestamp === 0) {
            //     this.startTimestamp = new Date().getTime()
            // }
            // if (this.preTime === 0) {
            //     this.preTime = new Date().getTime()
            // } else {
            //     const current = new Date().getTime()
            //     this.total = this.total + current - this.preTime
            //     this.preTime = current
            // }
            const arr = Array.from(data);
            this._handleData(arr)
        })
    }

    _handleData(arr) {
        let mappedData;
        if (isOpenMockSocket) {
            mappedData = this._mapReceiveMockData(arr);
        } else {
            mappedData = this._mapReceiveData(arr);
        }
        const firstRecordTime = mappedData[0].timestamp
        const isRecording = this.isCurrentDataInRecording(firstRecordTime)
        // console.log(mappedData[0].timestamp,new Date().getTime(),
        //     `${this.startTimestamp}`,`${this.totalRecordedCount}`)
        this.sendWSMsg(mappedData);
        if (isRecording) {
            let validData = fromJS(mappedData).toJS()
            this.recordedData = [...this.recordedData, ...validData]
        }
    }

    isCurrentDataInRecording(time){
        // console.log(this.startRecordTime,time,this.endRecordTime)
        return time >= this.startRecordTime && time <= this.endRecordTime
    }

    _mapReceiveMockData(arr) {
        const num = arr.length / 4;
        let ans = [];
        const currentTime = new Date().getTime()
        for (let i = 0; i < num; i++) {
            let obj = {};
            obj.timestamp = currentTime + i * 20
            const arr1 =  arr.slice(i * 4,(i + 1) * 4)
            const str1 = arr1.map(item => String.fromCharCode(item)).join('');
            obj.data = this.amplify * Number.parseInt(str1);
            // obj.data = (arr[4 * i + 2] << 8) + arr[4 * i + 3]
            obj.isValid = this.isCurrentDataInRecording(obj.timestamp)
            this.totalRecordedCount++;
            ans = [...ans, obj]
        }
        return ans
    }

    _mapReceiveData(arr) {
        const num = arr.length / 4;
        let ans = [];
        const currentTime = new Date().getTime()
        for (let i = 0; i < num; i++) {
            let obj = {};
            obj.timestamp = currentTime + i * 20
            obj.data = this.amplify * (arr[4 * i + 2] << 8) + arr[4 * i + 3];
            obj.isValid = this.isCurrentDataInRecording(obj.timestamp)
            this.totalRecordedCount++;
            /**
             * 平滑滤波
             */
            obj =  this.smooth_filter(obj)
            ans = [...ans, obj]
        }
        return ans;
    }

    smooth_filter(obj){
        if (this.window_data.length < this.windowLength){
            this.window_data.push(obj.data)
        }else {
            this.window_data.shift()
            this.window_data.push(obj.data)
        }
        const average = (this.window_data.reduce((acc,currentVal) => {
                return acc = acc + currentVal
            },0) / this.window_data.length
        ).toFixed(0)
        obj.data = average
        return obj
    }

    startRecord() {
        this.startRecordTime = new Date().getTime();
        this.endRecordTime = Number.MAX_SAFE_INTEGER;
        console.log('开始记录时间为:' + this.startRecordTime);
    }

    async stopRecord() {
        this.endRecordTime = new Date().getTime();
        console.log(`数组数据的起始时间是:${this.startTimestamp},当前总共收到数据量为:${this.totalRecordedCount}`);
        console.log(chalk.red(`记录总时长为:${(this.endRecordTime + 1000 - this.startRecordTime)}ms`));
        console.log(chalk.red(`采集开始时间：${this.startRecordTime},采集结束时间，${this.endRecordTime}`))
        const ans = await this.createFile();
        return ans
    }

    createFile() {
        return new Promise((resolve, reject) => {
            const arr = fromJS(this.recordedData)
            this.resetStatus()
            resolve(arr.toJS())
        })
    }

    resetStatus() {
        this.recordedData = [];
        this.startRecordTime = Number.MAX_SAFE_INTEGER;
    }

    sendWSMsg(mappedData) {
        this.collectData = [...this.collectData,...mappedData]
        if (cli !== null) {
            if (this.collectData.length >= 12){
                // console.log(`发送ws数据`)
                // cli.send(JSON.stringify({
                //     name:'Breathe',
                //     breatheVoList:this.collectData
                // }));
                cli.send(JSON.stringify(this.collectData));
                this.collectData = [];
            }
        }
    }
}
